//: Playground - noun: a place where people can play

import UIKit

var str = "Hello, playground"

//: 下标: 定义在类.结构体.枚举中,可以快速访问集合列表序列
//subscript(index: Int) -> Int {          // 下标语法, subscript(参数名: 参数类型) -> 返回值
//    get {                               // 语法类似于实例方法和计算属性语法的混合
//        // 返回一个整数类型
//    }
//    set(newValue) {                     // 下标可以设定为读写或者只读
//        // 执行赋值操作
//    }
//}

struct TimeTable {
    let multiplier: Int
    subscript(index: Int) -> Int {      // 用来表示传入整数的乘法
        return multiplier * index
    }                                   // 省略set,下标定义为只读的
}
let threeTimesTable = TimeTable(multiplier: 3) // 通过构造函数赋值给实例成员属性
print(threeTimesTable[6])               // 18, 通过下标访问实例传入参数并获取返回值



struct Matrix {
    var rows: Int, columns: Int
    subscript(row: Int, column: Int) -> Int { // 二维下标
        get {
            return rows + columns
        }
        set {                           // 默认参数newValue
            rows += newValue
            columns += newValue
            
            rows += row
            columns += column
        }
    }
}

var matrix = Matrix(rows: 2, columns: 3)
matrix[4,1] = 8
print(matrix.rows)
print(matrix.columns)

//:  继承: 一个类可以继承另一个类的方法,属性及其它特征
class Vehicle{
    var currentSpeed = 0.0
    var description: String{
        get{
            return "\(currentSpeed)公里/小时"
        }
    }
    func makeNoise(){
        
    }
}
let someVehicle = Vehicle()
print("速度: \(someVehicle.description)")

// 定义子类,子类获得父类的所有特性
class Bicycle: Vehicle{
    var hasTwoWheels = true
}
let bicycle = Bicycle()
bicycle.hasTwoWheels = true
bicycle.currentSpeed = 15.0             // 父类的属性
print("描述: \(bicycle.description)")   // 速度: 15.0公里/每小时

//子类还可以被其他类继承
class Tandem: Bicycle {                 // 双人自行车
    var canRideByTwoPeople = true
}

let tandem = Tandem()
tandem.hasTwoWheels = true
tandem.canRideByTwoPeople = true
tandem.currentSpeed = 10.0
print("描述: \(tandem.description)")    // 速度: 10.0公里/每小时

//:  重写: 子类可以对继承自父类的实例方法,类方法,实例属性,下标进行重写
class Train: Vehicle {
    var passenger = 20
    override var currentSpeed: Double { // 重写属性观察器
        didSet {
            passenger = Int(currentSpeed / 10)
        }
    }
    override func makeNoise() {         // 重写父类方法需要在前面加override关键字
        print("哐当哐当哐当哐")
    }
    override var description: String {  // 重写父类的属性
        return super.description + ",有\(passenger)个乘客" // super.description返回继承的值
    }
}
let train = Train()
train.makeNoise()                       // 调用重写的方法
print(train.description)                // 0.0公里/每小时,有0个乘客
train.currentSpeed = 200                // 调用属性观察器的didSet方法
print(train.description)                // 200.0公里/每小时,有20个乘客

//:  final关键字:防止方法 属性 下标被重写
//class Animal {
//    // 如果方法 属性 下标想不被重写, 可以在最前面添加关键字 final
//    final func run() {
//        print("Running!")
//    }
//}
//
//final class Dog: Animal {               // 在class前添加final,Dog类不可以被继承
//    override func run() {}              // ❌, run方法不可以被重写
//}






